我們寫外掛的時候,會要存資料到資料庫去,一般來說我們就存在 wp_options 表中,可以參考我在第十天分享的內容:如何修改 WordPress 的後台設置選項。或者就是可以存到 postmeta 或 usermeta 表中,可以參考第十一天的文章:如何管理 WordPress metadata。
不過還是會有些時候,這些不能滿足我們的需求,那我們就得需要單獨操作資料表了。這篇文章會來講講如何在寫外掛的時候去操作資料表。
一般在寫外掛時,創建資料表有如下三個步驟:
我們定義這個函式叫做 eric_crate_table()
,會長成這樣:
function eric_crate_table() {
global $wpdb;
$table_name = $wpdb->prefix . "eric";
if($wpdb->get_var("show tables like '$table_name'") != $weixin_robot_texts_table) {
$sql = "CREATE TABLE " . $table_name . " (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `keyword` (`keyword`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
}
接著我們逐一解釋。首先,預設 WordPress 資料表都是以 wp_
開頭,但也是會有例外,所以我們向 WordPress 資料庫建立表的時候,要先找找到資料庫表開頭。我們可以在變量 $wpdb->prefix
找到,如下:
global $wpdb;
$table_name = $wpdb->prefix . "eric";
接著,我們得去判斷表是否存在,我們可以通過一條 SHOW TABLES SQL 查詢來判斷。
if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name)
再來就是實際來創建一個資料表了。這裡不用直接的 SQL 查詢來創建,而是使用在 wp-admin/upgrade-functions.php
中的 dbDelta() 來建立,所以我們需要載入這個文件。 dbDelta() 函式很方便,他可以用來協助我們檢查當前的表結構。
$sql = "CREATE TABLE " . $tablename . " (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
我們使用 register_activation_hook()
hook 去掛上剛剛我們建立的 eric_crate_table()
函式。關於 register_activation_hook() 這個 hook 的介紹,可以參考我在第六天的介紹:WordPress 啟用、停用、刪除外掛 。
register_activation_hook( __FILE__,'eric_crate_table');
對於 WordPress 核心的文章、頁面、使用者...這類的資料,我們都可以可以通過 WordPress 內建的函式來完成,例如:我們可以透過 query_posts 來查詢文章。
但是,在很多時候,我們可能會定義自己的資料結構,這時,我們就需要了解 WordPress 的 WPDB,並嘗試借助 WPDB 來完成資料的操作。
在使用 WPDB 時,會需要掌握一定的 SQL 基礎,不過 SQL 基礎已經超過這篇文章的範圍了,我就不贅述。如果還不會使用 SQL 對資料庫進行增刪查改,那麼可能要先去學習一下 SQL 的基礎內容,再來繼續看下去。
WPDB 讓我們可以輕鬆的實現對 WordPress 資料庫的操作,讓我們可以完成自定義的資料操作需求。在使用 WPDB 時,我們可以直接使用 WordPrss 提供的 $wpdb 全局變數即可。
global $wpdb;
我們也可以使用 WPDB 進行 SQL 語句的查詢。我們會使用 $wpdb 的 query()。
global $wpdb;
$wpdb->query('query');
這個方法將會返回所執行的 SQL 語句影響的行數。如果回傳值是 0
或 false
,表示語句有問題。
在執行資料庫時,大部分時候需要查詢某筆資料。這個時候,就可以使用 get_row() 來取得。
global $wpdb;
$wpdb->get_row('query', output_type, row_offset);
get_row()
有三個參數:
object
,就是輸出一個物件。將其設置為 ARRAY_A
,會回傳一個 Key-Value 形式的陣列;設置為 ARRAY_N
,回傳一個排序過的陣列。剛剛我們去抓單個資料,但在某些情況下,我們需要取得某一個類型的所有資料。在這個時候,可以使用 get_results()。
global $wpdb;
$wpdb->get_results('query', output_type);
除了查詢以外,插入新的資料對於我們來說,也是非常重要的。 WordPress 同樣提供了插入的方法 insert()。
global $wpdb;
$wpdb->insert( $table, $data, $format );
執行 insert() 時,需要設置表名,並設置要添加的資料(預設需要是一個資料陣列)。 $format 是插入的類型,預設是 array ,不需要做修改。
在執行完成 insert 後,我們可以通過 $wpdb->insert_id
獲得插入後在表內的 id。
我們會查詢和新增了,接著我們還會遇到需要更新的時候,此時,我們可以執行 update() 來更新。
global $wpdb;
$wpdb->update( $table, $data, $where, $format = null, $where_format = null );
update() 的參數和前面幾個比,多了很多,但是其實也不難,我們來一一拆解。
在使用 update() 時,需要 $table
設置資料表名。 $data
則需要傳入我們要更改的資料,傳入的值為也是陣列類型。$where
則是傳入我們要抓來更新的條件陣列。$format
則是我們輸入的 data 的類型,預設是 array ,一般來說不需要動到。$where_format
則是是我們查詢的 where 的類型,預設也是 array,一般來說也不太會去修改他。
剩下最後一個操作了,就是刪除。我們可以使用 delete() 來刪除。
global $wpdb;
$wpdb->delete($table, $where, $where_format = null );
在使用 delete() 時,我們一樣需要 $table
設置資料表名。$where
則是傳入我們要抓來刪除的條件陣列。$where_format
則是是我們查詢的 where 的類型,預設 array,一般來說不太會去修改他。
WordPress 外掛如果想要上架到 WordPress.org 的話,會需要通過官方的安全檢查。
WordPress 的外掛審核團隊在審核外掛的時候,最主要的就是審查安全問題(通常也不會太在意你的外掛具體功能是什麼)。因此,在開發時,我們需要檢查我們的 SQL 語句安全,不會出現安全問題。
我們最怕的就是使用者在我們前台表單輸入資料的時候,做一些壞壞的事情,可能是 SQL injection 之類的(關於 SQL injection 可以上網 Google ,這也超出本篇範圍了,所以也不贅述。)。
因此, WordPress 官方提供了 prepare() 函式來協助我們預防使用者做壞事。該函式可以將使用者的輸入進行安全的轉換,從而確保進入資料庫的語句都是安全的。
$sql = $wpdb->prepare( 'query' [, value_parameter, value_parameter ... ] );
在使用時,我們需要使用 %s
,這樣的方式來替換 SQL 語句中的值,然後在第二個參數中的數組中傳入對應的值,進而進行 SQL 的處理,確保 SQL 語句的安全,就像這樣:
$wpdb->prepare( "
INSERT INTO $wpdb->postmeta( post_id, meta_key, meta_value ) VALUES ( %d, %s, %s )",
10, $metakey, $metavalue )
對於 WordPress 的資料庫操作介紹差不多就到這邊,wpdb class 底下還有很多好用的方法,可以直接去官方文件參考:wpdb